package com.vogue.supplymall.account.controller;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.google.gson.Gson;
import com.vogue.ssm.exception.UnknowException;
import com.vogue.supplymall.account.domain.model.AdminUser;
import com.vogue.supplymall.account.domain.service.impl.SpringContextUtils;
import com.vogue.supplymall.account.shiro.bean.TokenBean;
import com.vogue.supplymall.account.shiro.realm.AdminUserRealm;
import com.vogue.supplymall.account.shiro.token.AdminUPToken;
import com.vogue.supplymall.common.domain.tool.CodeProcessUtils;
import com.vogue.supplymall.common.domain.validate.Regex;

/**
 * 管理员登录
 * @author 崔岳
 *
 */
@Validated
@RestController
public class AdminLoginController extends BaseController {

    public static final Logger LOGGER_ADMINLOGINCONTROLLER = LoggerFactory.getLogger(AdminLoginController.class);

    /**
     * 登录接口
     * @param appver 版本号
     * @param request 请求对象
     * @return ResponseEntity<Map<String, String>>
     * @throws Exception 登录异常
     */
    @RequestMapping("/ns/{appver}/admin/account/login")
    public ResponseEntity<Map<String, String>> login(
            @PathVariable("appver") @Regex(name = "appver", regexcontent = "vernum") String appver,
            HttpServletRequest request) throws Exception {
        String username = null;
        String password = null;
        String loginInfo = null;
        if (loginInfo == null) {
            username = request.getParameter("username");
            password = request.getParameter("password");
            if (username == null) {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader((ServletInputStream) request.getInputStream(), "utf-8"));
                StringBuffer sb = new StringBuffer("");
                String temp;
                String params = null;
                try {
                    while ((temp = br.readLine()) != null) {
                        sb.append(temp);
                    }
                    params = sb.toString();
                } finally {
                    if (br != null) {
                        br.close();
                    }
                }
                Gson json = new Gson();
                TokenBean bean = json.fromJson(params, TokenBean.class);
                username = bean.getUsername();
                password = bean.getPassword();
                if (StringUtils.isEmpty(bean.getUsername())) {
                    if (bean.getLogininfo() != null) {
                        loginInfo = new String(CodeProcessUtils.decode(bean.getLogininfo()));
                        TokenBean loginBean = json.fromJson(loginInfo, TokenBean.class);
                        username = loginBean.getUsername();
                        password = loginBean.getPassword();
                    }
                }
            }
        }

        Subject subject = SecurityUtils.getSubject();
        if (SecurityUtils.getSubject().isAuthenticated()) {
            subject.logout();
        }
        try {
            AdminUPToken token = new AdminUPToken(username, password);
            subject.login(token);
        } catch (Exception ex) {
            LOGGER_ADMINLOGINCONTROLLER.error("authrealm identity login error : " + ex.toString());
            if (ex instanceof org.apache.shiro.authc.UnknownAccountException) {
                throw new com.vogue.supplymall.common.exception.IncorrectCredentialsException();
            } else if (ex instanceof org.apache.shiro.authc.IncorrectCredentialsException) {
                throw new com.vogue.supplymall.common.exception.IncorrectCredentialsException();
            } else if (ex instanceof org.apache.shiro.authc.ExcessiveAttemptsException) {
                throw new com.vogue.supplymall.common.exception.ExcessiveAttemptsException(username);
            } else if (ex instanceof org.apache.shiro.authc.LockedAccountException) {
                throw new com.vogue.supplymall.common.exception.LockedAccountException(username);
            } else {
                throw new UnknowException("Find msg in log");
            }
        }
        loginInfo = CodeProcessUtils.encode(("{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}").getBytes());
        Map<String, String> map = new HashMap<String, String>();
        map.put("loginInfo", loginInfo);
        return new ResponseEntity<Map<String, String>>(map, HttpStatus.OK);
    }

    /**
    * 退出登录
    * @param appver 版本号
    * @param request 请求对象
    * @return ResponseEntity<Map<String, String>>
    * @throws Exception 退出异常
    */
    @RequestMapping("/ns/{appver}/admin/account/logout")
    public ResponseEntity<Map<String, String>> logout(
            @PathVariable("appver") @Regex(name = "appver", regexcontent = "vernum") String appver,
            HttpServletRequest request) throws Exception {
        if (SecurityUtils.getSubject() != null && SecurityUtils.getSubject().isAuthenticated()) {
            AdminUser info = (AdminUser) SecurityUtils.getSubject().getPrincipal();
            AdminUserRealm authRealm = (AdminUserRealm) SpringContextUtils.getBeanByClass(AdminUserRealm.class);
            if (authRealm != null) {
                authRealm.clearAllCache(
                        new SimplePrincipalCollection(AdminUserRealm.getCacheKey(info.getLoginname()), authRealm.getName()));
            }
            SecurityUtils.getSubject().logout();
        }
        Map<String, String> map = new HashMap<String, String>();
        map.put("info", "logout");
        return new ResponseEntity<Map<String, String>>(map, HttpStatus.OK);
    }
}
